package cn.lingyangwl.framework.mock.data.manager.impl;

import cn.lingyangwl.framework.mock.data.generator.MockDataGenerator;
import cn.lingyangwl.framework.mock.data.model.MysqlTableColumn;
import cn.lingyangwl.framework.mock.data.manager.GenMockDataManager;
import com.github.yitter.idgen.YitIdHelper;
import cn.lingyangwl.framework.tool.core.StringUtils;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author shenguangyang
 */
@Slf4j
public class GenMysqlDataManagerImpl implements GenMockDataManager {
    @Override
    public Map<String, Object> create(MockDataGenerator mockDataGeneratorReq, List<MysqlTableColumn> tableColumnList) {
        Map<String, Object> resp = new HashMap<>();
        Optional<MockDataGenerator> dataGenerator = Optional.ofNullable(mockDataGeneratorReq);
        tableColumnList.forEach(tableColumn -> {
            String dataType = tableColumn.getDataType();
            String columnKey = tableColumn.getColumnKey();
            if (StringUtils.isNotEmpty(columnKey)) {
                resp.put(tableColumn.getColumnName(), YitIdHelper.nextId());
            } else if ("varchar".equals(dataType) || "text".equals(dataType) || "char".equals(dataType)
                    || "blob".equals(dataType) || "tinytext".equals(dataType) || "tinyblob".equals(dataType)) {
                Object data = dataGenerator.map(x -> x.data().get(tableColumn.getColumnName())).map(x -> x.apply(tableColumn))
                        .orElse("1");
                resp.put(tableColumn.getColumnName(), data);
            } else if ("datetime".equals(dataType)) {
                Object data = dataGenerator.map(x -> x.data().get(tableColumn.getColumnName())).map(x -> x.apply(tableColumn))
                        .orElse(LocalDateTime.now());
                resp.put(tableColumn.getColumnName(), data);
            } else if ("date".equals(dataType)) {
                Object data = dataGenerator.map(x -> x.data().get(tableColumn.getColumnName())).map(x -> x.apply(tableColumn))
                        .orElse(LocalDateTime.now());
                resp.put(tableColumn.getColumnName(), data);
            } else if ("bigint".equals(dataType)) {
                Object data = dataGenerator.map(x -> x.data().get(tableColumn.getColumnName())).map(x -> x.apply(tableColumn))
                        .orElse(1L);
                resp.put(tableColumn.getColumnName(), data);
            } else if ("int".equals(dataType) || "tinyint".equals(dataType)) {
                Object data = dataGenerator.map(x -> x.data().get(tableColumn.getColumnName())).map(x -> x.apply(tableColumn))
                        .orElse(1);
                resp.put(tableColumn.getColumnName(), data);
            } else if ("float".equals(dataType)) {
                Object data = dataGenerator.map(x -> x.data().get(tableColumn.getColumnName())).map(x -> x.apply(tableColumn))
                        .orElse(1F);
                resp.put(tableColumn.getColumnName(), data);
            } else if ("double".equals(dataType)) {
                Object data = dataGenerator.map(x -> x.data().get(tableColumn.getColumnName())).map(x -> x.apply(tableColumn))
                        .orElse(BigDecimal.valueOf(1D));
                resp.put(tableColumn.getColumnName(), data);
            } else if ("decimal".equals(dataType)) {
                Object data = dataGenerator.map(x -> x.data().get(tableColumn.getColumnName())).map(x -> x.apply(tableColumn))
                        .orElse(BigDecimal.valueOf(1L));
                resp.put(tableColumn.getColumnName(), data);
            } else {
                log.warn("not find columnName [{}] dataType [{}]", tableColumn.getColumnName(), tableColumn.getDataType());
                Object data = dataGenerator.map(x -> x.data().get(tableColumn.getColumnName())).map(x -> x.apply(tableColumn))
                        .orElse("1");
                resp.put(tableColumn.getColumnName(), data);
            }
        });
        return resp;
    }
}
